package coop.bancocredicoop.proyectos.gd.rbac;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import coop.bancocredicoop.proyectos.gd.FrontEndMessage;
import coop.bancocredicoop.proyectos.gd.rbac.procedure.AddUserToAlfrescoGroupsProcedure;
import coop.bancocredicoop.proyectos.gd.rbac.procedure.RemoveUserFromAlfrescoGroupsProcedure;

public class RBACFilter implements Filter {

	private static final Log log = LogFactory.getLog(RBACFilter.class);
	private static final String loginErrorJsp = "/jsp/loginError.jsp";
	private static final String errorAutorizacion = "Error contactando al módulo de autorización.";

	public void doFilter(final ServletRequest request,
			final ServletResponse response, FilterChain chain)
			throws java.io.IOException, javax.servlet.ServletException  {

		HttpServletRequest _request = (HttpServletRequest) request;
		response.setCharacterEncoding("UTF8");
		
		if (_request.getSession().getAttribute("rbac") == null) {
			RBAC rbac = null;

			try {
				rbac = new RBACFactory().getRBAC(_request.getSession(),
						_request.getRemoteUser());

				_request.getSession().setAttribute("rbac", rbac);
				_request.getSession().setAttribute("usuario", rbac.getUsuario());
			} catch (Exception e) {
				log.error("Error obteniendo el usuario de RBAC", e);
				setAuthorizationError(_request, errorAutorizacion);
				request.getRequestDispatcher(loginErrorJsp).forward(request, response);
				return;
			}
			
			if (rbac != null) {
				try {
					new AddUserToAlfrescoGroupsProcedure().run(rbac);
					new RemoveUserFromAlfrescoGroupsProcedure().run(rbac);
				} catch (Exception e) {
					log.error("Error sincronizando los grupos de Alfresco con RBAC", e);
					setAuthorizationError(_request, errorAutorizacion);
					request.getRequestDispatcher(loginErrorJsp).forward(request, response);
					return;
				}
			}

		}

		chain.doFilter(request, response);
	}

	private void setAuthorizationError(HttpServletRequest _request, String message) {
		_request.getSession().removeAttribute("rbac");
		_request.getSession().removeAttribute("usuario");
		_request.getSession().invalidate();
		FrontEndMessage frontEndMessage = new FrontEndMessage();
		frontEndMessage.addErrorMessage(message);
		frontEndMessage.setMessagesInSession(_request);
	}

	public void destroy() {
	}

	public void init(FilterConfig arg0) throws ServletException {
	}

}
